<?php

namespace common\models\c2\entity;

use common\models\c2\statics\WarehouseNoteItemStatus;
use common\models\c2\statics\WarehouseNoteState;
use cza\base\models\ActiveRecord;
use cza\base\models\statics\EntityModelStatus;
use Yii;
use yii\behaviors\BlameableBehavior;
use yii\helpers\ArrayHelper;
use yii\validators\RequiredValidator;

/**
 * This is the model class for table "{{%warehouse_note}}".
 *
 * @property string $id
 * @property integer $type
 * @property integer $ref_note_id
 * @property string $ref_note_code
 * @property string $label
 * @property integer $warehouse_id
 * @property string $receiver_name
 * @property integer $updated_by
 * @property integer $created_by
 * @property string $memo
 * @property integer $state
 * @property integer $status
 * @property integer $position
 * @property string $created_at
 * @property string $updated_at
 */
class WarehouseNote extends \cza\base\models\ActiveRecord
{

    public $items;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%warehouse_note}}';
    }

    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            BlameableBehavior::className()
        ]); // TODO: Change the autogenerated stub
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['ref_note_id', 'warehouse_id', 'updated_by', 'created_by', 'position'], 'integer'],
            [['memo'], 'string'],
            [['items'], 'validateItems'],
            [['created_at', 'updated_at', 'commit_at'], 'safe'],
            [['type'], 'integer', 'max' => 9],
            [['ref_note_code', 'label', 'receiver_name'], 'string', 'max' => 255],
            [['state', 'status'], 'integer', 'max' => 4],
        ];
    }

    public function validateItems($attribute)
    {
        $items = $this->$attribute;

        foreach ($items as $index => $row) {
            $requiredValidator = new RequiredValidator();
            $error = null;
            $requiredValidator->validate($row['product_id'], $error);
            if (!empty($error)) {
                $key = $attribute . '[' . $index . '][product_id]';
                // $this->addError($key, Yii::t('app.c2', 'Product/Combination/Package not be null.'));
                $this->addError($key, Yii::t('app.c2', '{attribute} can not be empty!', ['attribute' => Yii::t('app.c2', 'Product')]));
            }
        }
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app.c2', 'ID'),
            'type' => Yii::t('app.c2', 'Type'),
            'ref_note_id' => Yii::t('app.c2', 'Ref Note ID'),
            'ref_note_code' => Yii::t('app.c2', 'Ref Note Code'),
            'label' => Yii::t('app.c2', 'Label'),
            'warehouse_id' => Yii::t('app.c2', 'Warehouse ID'),
            'receiver_name' => Yii::t('app.c2', 'Receiver Name'),
            'updated_by' => Yii::t('app.c2', 'Updated By'),
            'created_by' => Yii::t('app.c2', 'Created By'),
            'memo' => Yii::t('app.c2', 'Memo'),
            'state' => Yii::t('app.c2', 'State'),
            'status' => Yii::t('app.c2', 'Status'),
            'position' => Yii::t('app.c2', 'Position'),
            'created_at' => Yii::t('app.c2', 'Created At'),
            'updated_at' => Yii::t('app.c2', 'Updated At'),
        ];
    }

    /**
     * @inheritdoc
     * @return \common\models\c2\query\WarehouseNoteQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new \common\models\c2\query\WarehouseNoteQuery(get_called_class());
    }

    public function getDeliveryNote()
    {
        return $this->hasOne(InventoryDeliveryNote::className(), ['id' => 'ref_note_id']);
    }

    /**
     * setup default values
     **/
    public function loadDefaultValues($skipIfSet = true)
    {
        parent::loadDefaultValues($skipIfSet);
        if ($this->isNewRecord) {
            $this->state = WarehouseNoteState::INIT;
        }
    }

    public function getNoteItems()
    {
        return $this->hasMany(WarehouseNoteItem::className(), ['note_id' => 'id']);
    }

    public function loadItems()
    {
        $this->items = $this->getNoteItems()->all();
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub
        if (!empty($this->items)) {
            foreach ($this->items as $item) {
                $product = Product::findOne($item['product_id']);
                $pieces = isset($item['pieces']) ? $item['pieces'] : 0;
                $price = isset($item['price']) ? $item['price'] : 0.0000;
                $number = isset($item['number']) ? $item['number'] : 0;
                $subtotal = $price * $number;
                if (!is_null($product)) {
                    $attributes = [
                        'ref_note_id' => $this->ref_note_id,
                        'product_id' => $product->id,
                        'product_name' => $product->name,
                        'product_label' => $product->label,
                        'product_sku' => $product->sku,
                        'product_value' => $product->value,
                        'combination_id' => null,
                        'combination_name' => null,
                        'package_id' => null,
                        'package_name' => null,
                        'measure_id' => isset($item['measure_id']) ? $item['measure_id'] : 0,
                        'number' => isset($item['product_sum']) ? $item['product_sum'] : 0,
                        'pieces' => $pieces,
                        'price' => $price,
                        'subtotal' => $subtotal,
                        'memo' => isset($item['memo']) ? $item['memo'] : '',
                        'status' => WarehouseNoteItemStatus::INIT,
                    ];
                    if (isset($item['number'])) {
                        $attributes['number'] = $item['number'];
                    }
                    if (isset($item['combination_id'])) {
                        $comb = ProductCombination::findOne($item['combination_id']);
                        if (!is_null($comb)) {
                            $attributes['combination_id'] = $comb->id;
                            $attributes['combination_name'] = $comb->name;
                        }
                    }
                    if (isset($item['package_id'])) {
                        $package = ProductPackage::findOne($item['package_id']);
                        if (!is_null($package)) {
                            $attributes['package_id'] = $package->id;
                            $attributes['package_name'] = $package->name;
                            $attributes['number'] = $package->product_capacity * $pieces;
                        }
                    }
                    if (isset($item['product_sum'])) {
                        $attributes['number'] = $item['product_sum'];
                    }
                    if (isset($item['id']) && $item['id'] == '') {
                        $itemModel = new WarehouseNoteItem();
                        $itemModel->setAttributes($attributes);
                        $itemModel->link('owner', $this);
                    } elseif (isset($item['id'])) {
                        $itemModel = WarehouseNoteItem::findOne($item['id']);
                        if (!is_null($itemModel)) {
                            $itemModel->updateAttributes($attributes);
                        }
                    }
                }
            }
        }
    }

    public function beforeDelete()
    {
        foreach ($this->noteItems as $noteItem) {
            $noteItem->delete();
        }
        return parent::beforeDelete(); // TODO: Change the autogenerated stub
    }

    public function getInventoryDeliveryNote()
    {
        return $this->hasOne(InventoryDeliveryNote::className(), ['id' => 'ref_note_id']);
    }

    /**
     * 采购进仓
     */
    public function setReceiptNoteStateToCommit()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            ->with('product')
            ->all();
        if (!empty($items)) {
            foreach ($items as $item) {
                $item->product->updateStock($item->number);
                // $item->product->updateCounters(['stock' => $item->number]);
                $item->updateAttributes(['status' => WarehouseNoteItemStatus::COMMIT]);
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

    public function setProductionScheduleNoteToCommit()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            ->with('productCombination')
            // ->with('scheduleNoteItems')
            ->all();
        if (!empty($items)) {
            foreach ($items as $item) {
                if (!is_null($item->productCombination)) {
                    // $item->productCombination->stock = $item->productCombination->stock + $item->number;
                    // $item->productCombination->save();
                    $item->productCombination->updateCounters(['stock' => $item->number]);
                    $item->productCombination->updated_at = date('Y-m-d h:i:s', time());
                    $item->productCombination->update();
                    $item->product->updateCounters(['stock' => $item->number,]);
                    $item->product->updated_at = date('Y-m-d h:i:s', time());
                    $item->product->update();
                    $item->scheduleItem->updateCounters(['enter_sum' => $item->number]);
                }
                // if (!is_null($item->scheduleNoteItems)) {
                //     $item->scheduleNoteItems->updateCounters(['enter_sum' => $item->number]);
                // }
                $item->updateAttributes(['status' => WarehouseNoteItemStatus::COMMIT]);
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

    public function setDeliveryNoteToCommit()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            ->with('productCombination')
            ->with('product')
            ->all();
        $note = $this->inventoryDeliveryNote;
        if (!empty($items)) {
            foreach ($items as $item) {
                if (!is_null($item->productCombination)) {
                    // $item->productCombination->stock = $item->productCombination->stock + $item->number;
                    // $item->productCombination->save();
                    $item->productCombination->updateCounters(['stock' => -($item->number)]);
                    $item->productCombination->updated_at = date('Y-m-d h:i:s', time());
                    $item->productCombination->update();
                }
                $item->product->updateCounters(['stock' => -($item->number)]);
                $item->product->updated_at = date('Y-m-d h:i:s', time());
                $item->product->update();
                $orderItem = OrderItem::findOne(['order_id' => $note->sales_order_id, 'product_id' => $item->product_id]);
                $orderItem->updateCounters([
                    'produced_number' => $item->number,
                    'send_pieces' => $item->pieces,
                ]);
                $item->updateAttributes(['status' => WarehouseNoteItemStatus::COMMIT]);
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

    public function setMixtureSendNoteToCommit()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            // ->with('product')
            // ->with('productionConsumption')
            ->all();
        if (!empty($items)) {
            foreach ($items as $item) {
                $model = ProductionConsumption::findOne([
                    'schedule_id' => $this->ref_note_id,
                    'need_product_id' => $item->product_id
                ]);
                $model->updateCounters(['send_sum' => $item->number]);
                $item->product->updateCounters(['stock' => -($item->number)]);
                $item->product->updated_at = date('Y-m-d h:i:s', time());
                $item->product->update();
                $item->updateAttributes(['status' => WarehouseNoteItemStatus::COMMIT]);
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

    /**
     * 加工物料进仓
     */
    public function setReceiptMaterialToCommit()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            // ->with('scheduleNoteItems')
            ->all();
        if (!empty($items)) {
            foreach ($items as $item) {
                $model = ProductionScheduleItem::findOne([
                    'schedule_id' => $this->ref_note_id,
                    'enter_product_id' => $item->product_id
                ]);
                $model->updateCounters(['enter_sum' => $item->number]);
                $item->product->updateCounters(['stock' => $item->number]);
                $item->product->updated_at = date('Y-m-d h:i:s', time());
                $item->product->update();
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

    /**
     * 生产物料进仓
     */
    public function setReceiptMaterialToCommit1()
    {
        if ($this->state == WarehouseNoteState::COMMIT) {
            return;
        }
        $items = $this->getNoteItems()
            // ->with('scheduleNoteItems')
            ->all();
        if (!empty($items)) {
            foreach ($items as $item) {
                $model = ProductionScheduleItem::findOne([
                    'schedule_id' => $this->ref_note_id,
                    'product_id' => $item->product_id
                ]);
                $model->updateCounters(['enter_sum' => $item->number]);
                // $item->product->updateCounters(['stock' => $item->number]);
                $product = $item->product->updateStock($item->number);
            }
        }
        $this->updateAttributes(['state' => WarehouseNoteState::COMMIT]);
    }

}
